/*
 * Copyright 2017 Baiyyy
 * @(#)ColdStorageService.java
 */

package com.byyy.ccts.modules.ysjl.service.impl;

import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.byyy.ccts.core.common.service.impl.CommonServiceImpl;
import com.byyy.ccts.core.message.rocketmq.OAProducer;
import com.byyy.ccts.core.query.data.Condition;
import com.byyy.ccts.core.query.data.PageImpl;
import com.byyy.ccts.core.query.data.Pageable;
import com.byyy.ccts.core.query.data.Queryable;
import com.byyy.ccts.core.query.parse.QueryToWrapper;
import com.byyy.ccts.core.query.wrapper.EntityWrapper;
import com.byyy.ccts.core.utils.BeanUtils;
import com.byyy.ccts.core.utils.DateUtils;
import com.byyy.ccts.core.utils.SpringContextHolder;
import com.byyy.ccts.core.utils.StringUtils;
import com.byyy.ccts.core.utils.http.HttpUtils;
import com.byyy.ccts.modules.cc.Global;
import com.byyy.ccts.modules.ysjl.YsjlGlobal;
import com.byyy.ccts.modules.ysjl.entity.*;
import com.byyy.ccts.modules.ysjl.enums.ActivityCateEnum;
import com.byyy.ccts.modules.ysjl.enums.ActivityStatusEnum;
import com.byyy.ccts.modules.ysjl.mapper.YsjlActivityMapper;
import com.byyy.ccts.modules.ysjl.reqvo.FormReqVo;
import com.byyy.ccts.modules.ysjl.service.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by DELL on 2018-6-13.
 */
@Transactional
@Service("ysjlActivityService")
public class YsjlActivityService extends CommonServiceImpl<YsjlActivityMapper, YsjlActivity> implements IYsjlActivityService {

    @Autowired
    private IYsjlActivityEnrollService ysjlActivityEnrollService;

    @Autowired
    private IYsjlActivityPicService ysjlActivityPicService;

    @Autowired
    private IYsjlActivityFlowService ysjlActivityFlowService;

    @Autowired
    private IYsjlLogService ysjlLogService;

    @Autowired
    private IYsjlUserService ysjlUserService;

    @Override
    public com.byyy.ccts.core.query.data.Page<YsjlActivity> pageActivityList(Queryable queryable, EntityWrapper<YsjlActivity> wrapper) {
        QueryToWrapper<YsjlActivity> queryToWrapper = new QueryToWrapper<>();
        // 排序问题
        queryToWrapper.parseCondition(wrapper, queryable);
        queryToWrapper.parseSort(wrapper, queryable);
        Pageable pageable = queryable.getPageable();
        com.baomidou.mybatisplus.plugins.Page<YsjlActivity> page = new com.baomidou.mybatisplus.plugins.Page<YsjlActivity>(
                pageable.getPageNumber(), pageable.getPageSize());
        com.baomidou.mybatisplus.plugins.Page<YsjlActivity> content = this.listPage(page, wrapper);
        List<YsjlActivity> activityList = content.getRecords();
        if (activityList != null && !activityList.isEmpty()) {
            for (YsjlActivity activity : activityList) {
                if (ActivityStatusEnum.GOON.getCode() == activity.getStatus()) {
                    if (DateUtils.getSecondOfTwoDate(activity.getStartTime(), new Date()) > 0) {
                        activity.setStatus(ActivityStatusEnum.OVER.getCode());
                    }
                }
                activity.setShowTime(DateUtils.formatDate(activity.getStartTime(), "yyyy-MM-dd HH:mm")
                        + "~" + DateUtils.formatDate(activity.getEndTime(), "HH:mm"));
                activity.setStatusName(ActivityStatusEnum.getMsgByCode(activity.getStatus()));
                activity.setCateName(ActivityCateEnum.getMsgByCode(activity.getCateId()));
            }
        }

        return new PageImpl<YsjlActivity>(content.getRecords(), queryable.getPageable(), content.getTotal());
    }

    public Page<YsjlActivity> listPage(Page<YsjlActivity> page, Wrapper<YsjlActivity> wrapper) {
        page.setRecords(baseMapper.queryActivityListPage(page, wrapper));
        return page;
    }

    @Override
    public com.byyy.ccts.core.query.data.Page<YsjlActivity> queryUserActivityListPage(Queryable queryable, EntityWrapper<YsjlActivity> wrapper) {
        QueryToWrapper<YsjlActivity> queryToWrapper = new QueryToWrapper<>();
        Condition condition = queryable.getCondition();
        Condition.Filter userIdFilter = condition.getFilterFor("userId");
        String userId = null;
        if (userIdFilter != null) {
            userId = (String) userIdFilter.getValue();
            condition.remove(userIdFilter);
        }
        Pageable pageable = queryable.getPageable();
        com.baomidou.mybatisplus.plugins.Page<YsjlActivity> page = new com.baomidou.mybatisplus.plugins.Page<YsjlActivity>(
                pageable.getPageNumber(), pageable.getPageSize());
        com.baomidou.mybatisplus.plugins.Page<YsjlActivity> content = this.userListPage(page, wrapper, userId);
        List<YsjlActivity> activityList = content.getRecords();
        if (activityList != null && !activityList.isEmpty()) {
            for (YsjlActivity activity : activityList) {
                if (ActivityStatusEnum.GOON.getCode() == activity.getStatus()) {
                    if (DateUtils.getSecondOfTwoDate(activity.getStartTime(), new Date()) > 0) {
                        activity.setStatus(ActivityStatusEnum.OVER.getCode());
                    }
                }
                activity.setShowTime(DateUtils.formatDate(activity.getStartTime(), "yyyy-MM-dd HH:mm")
                        + "~" + DateUtils.formatDate(activity.getEndTime(), "HH:mm"));
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(activity.getStartTime());
                activity.setWeek(YsjlGlobal.WEEK[calendar.get(Calendar.DAY_OF_WEEK) - 1]);
                activity.setStatusName(ActivityStatusEnum.getMsgByCode(activity.getStatus()));
                activity.setCateName(ActivityCateEnum.getMsgByCode(activity.getCateId()));
            }
        }
        return new PageImpl<YsjlActivity>(content.getRecords(), queryable.getPageable(), content.getTotal());
    }

    public Page<YsjlActivity> userListPage(Page<YsjlActivity> page, Wrapper<YsjlActivity> wrapper, String userId) {
        page.setRecords(baseMapper.queryUserActivityListPage(page, wrapper, userId));
        return page;
    }

    @Override
    public List<YsjlActivity> queryList(String userId) {
        List<YsjlActivity> activityList = this.baseMapper.queryList(userId);
        if (activityList == null || activityList.isEmpty()) {
            return null;
        }

        List<YsjlActivityEnroll> enrollList = null;
        for (YsjlActivity activity : activityList) {
            activity.setShowTime(DateUtils.formatDate(activity.getStartTime(), "yyyy-MM-dd HH:mm")
                    + "~" + DateUtils.formatDate(activity.getEndTime(), "HH:mm"));
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(activity.getStartTime());
            activity.setWeek(YsjlGlobal.WEEK[calendar.get(Calendar.DAY_OF_WEEK) - 1]);
            enrollList = this.ysjlActivityEnrollService.queryListByActivityId(activity.getId());
            activity.setEnrollList(enrollList);
            activity.setJoinCnt(enrollList == null ? 0 : enrollList.size());
            if (StringUtils.isNotEmpty(activity.getUserId())) {
                activity.setCurrentUser(true);
            }
        }
        return activityList;
    }

    @Override
    public List<YsjlActivity> queryMyActivityList(String userId) {
        if (StringUtils.isEmpty(userId)) {
            return null;
        }
        List<YsjlActivity> activityList = this.baseMapper.queryMyActivityList(userId);
        if (activityList == null || activityList.isEmpty()) {
            return null;
        }

        List<YsjlActivityEnroll> enrollList = null;
        for (YsjlActivity activity : activityList) {
            activity.setShowTime(DateUtils.formatDate(activity.getStartTime(), "yyyy-MM-dd HH:mm")
                    + "~" + DateUtils.formatDate(activity.getEndTime(), "HH:mm"));
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(activity.getStartTime());
            activity.setWeek(YsjlGlobal.WEEK[calendar.get(Calendar.DAY_OF_WEEK) - 1]);
            enrollList = this.ysjlActivityEnrollService.queryListByActivityId(activity.getId());
            activity.setEnrollList(enrollList);
            activity.setJoinCnt(enrollList == null ? 0 : enrollList.size());
            if (StringUtils.isNotEmpty(activity.getUserId())) {
                activity.setCurrentUser(true);
            }
        }
        return activityList;
    }

    @Override
    public YsjlActivity activityInfo(String activityId, String userId) {
        YsjlActivity activity = this.selectById(activityId);
        int userJoinCnt = 0;
        List<YsjlActivityEnroll> activityEnrollList = this.ysjlActivityEnrollService.queryListByActivityId(activityId);
        if (activityEnrollList != null && !activityEnrollList.isEmpty() && StringUtils.isNotEmpty(userId)) {
            for (YsjlActivityEnroll enroll : activityEnrollList) {
                if (enroll.getUserId().equals(userId)) {
                    activity.setUserId(enroll.getUserId());
                    enroll.setCurrentUser(true);
                    userJoinCnt++;
                }
            }
        }
        activity.setHour(DateUtils.getSecondOfTwoDate(activity.getStartTime(), activity.getEndTime()) / 3600);
        activity.setEnrollList(activityEnrollList);
        activity.setJoinCnt(activityEnrollList == null ? 0 : activityEnrollList.size());
        activity.setUserJoinCnt(userJoinCnt);
        activity.setShowTime(DateUtils.formatDate(activity.getStartTime(), "yyyy-MM-dd HH:mm")
                + "~" + DateUtils.formatDate(activity.getEndTime(), "HH:mm"));
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(activity.getStartTime());
        activity.setWeek(YsjlGlobal.WEEK[calendar.get(Calendar.DAY_OF_WEEK) - 1]);
        List<YsjlActivityPic> activityPicList = this.ysjlActivityPicService.queryListByActivityId(activityId);
        List<YsjlActivityFlow> activityFlowList = this.ysjlActivityFlowService.queryListByActivityId(activityId);
        // 获取默认活动图片
        if (activityPicList == null || activityPicList.isEmpty()) {
            activity.setPicList(Arrays.asList(YsjlGlobal.PIC_DEFAULT));
        }
        else {
            List<String> picList = new ArrayList<>();
            for (YsjlActivityPic pic : activityPicList) {
                picList.add(pic.getPic());
            }
            activity.setPicList(picList);
        }
        // 获取默认流程
        if (activityFlowList == null || activityFlowList.isEmpty()) {
            YsjlActivityFlow activityFlow = null;
            activityFlowList = new ArrayList<>();
            for(String flow : YsjlGlobal.FLOW_DEFAULT) {
                activityFlow = new YsjlActivityFlow();
                activityFlow.setActivityId(activityId);
                activityFlow.setTitle(flow);
                activityFlowList.add(activityFlow);
            }
            activity.setFlowList(activityFlowList);
        }
        else {
            activity.setFlowList(activityFlowList);
        }

        List<FormReqVo> forms = new ArrayList<>();
        // 构筑活动费用
        FormReqVo form = new FormReqVo();
        form.setMark("fee");
        form.setTitle("活动费用");
        form.setType("text");
        form.setVal(activity.getFee());
        forms.add(form);
        // 构筑活动封面
        form = new FormReqVo();
        form.setMark("cover");
        form.setTitle("活动封面");
        form.setMin(1);
        form.setMax(1);
        form.setType("image");
        form.setVal(Arrays.asList(new String[] {activity.getPic()}));
        forms.add(form);
        // 构筑活动图集
        form = new FormReqVo();
        form.setMark("img");
        form.setTitle("活动封面");
        form.setMin(1);
        form.setMax(8);
        form.setType("image");
        List<String> picList = new ArrayList<>();
        if (activityPicList != null && !activityPicList.isEmpty()) {
            for (YsjlActivityPic pic : activityPicList) {
                picList.add(pic.getPic());
            }
        }
        form.setVal(picList);
        forms.add(form);
        // 构筑流程
        form = new FormReqVo();
        form.setMark("flow");
        form.setTitle("活动图集");
        form.setMin(1);
        form.setMax(8);
        form.setType("rows");
        List<Map<String, Object>> flowVal = new ArrayList<>();
        Map<String, Object> flowObj = null;
        if (!activityFlowList.isEmpty()) {
            for (YsjlActivityFlow flow : activityFlowList) {
                flowObj = new HashMap<>();
                flowObj.put("title", flow.getTitle());
                flowObj.put("edit", true);
                flowObj.put("mark", "SWIIDHVHEW");
                flowVal.add(flowObj);
            }
        }
        else {
            flowObj = new HashMap<>();
            flowObj.put("title", "默认流程");
            flowObj.put("edit", true);
            flowObj.put("mark", "SWIIDHVHEW");
            flowVal.add(flowObj);
        }
        form.setVal(flowVal);
        forms.add(form);
        activity.setForms(forms);

        return activity;
    }

    @Override
    public String submitActivity(HttpServletRequest request, YsjlActivity activity) {
        if (DateUtils.getSecondOfTwoDate(activity.getStartTime(), new Date()) > 0) {
            return "开始时间太早";
        }
        activity.setStatus(ActivityStatusEnum.GOON.getCode());
        activity.setFee("2-3小时，人均30-40！");
        activity.setPic("http://ccc.baheal.com/byyyccctest/static/ysjl/logo/logoVertical.png");
        activity.setAddTime(new Timestamp(System.currentTimeMillis()));
        activity.setTitle(activity.getTitle() + " " + DateUtils.formatDate(activity.getStartTime(), "yyyyMMdd"));
        this.setAddressGeo(activity);
        this.insert(activity);

        this.generateQRCode(request, activity.getId(), "/projects/activityyu/pages/default/index/default_index");


        /*
        // 获取活动费用
        FormReqVo formReqVo = activity.getForms().get(0);
        String feeVal = (String) formReqVo.getVal();
        if (StringUtils.isNotEmpty(feeVal)) {
            activity.setFee(feeVal);
        }
        else {
            activity.setFee("2-3小时，人均30-40！");
        }

        // 获取封面图片
        formReqVo = activity.getForms().get(1);
        List<String> picVal = (List) formReqVo.getVal();
        if (picVal != null && picVal.size() > 0) {
            activity.setPic(picVal.get(0));
        }
        else {
            activity.setPic("http://ccc.baheal.com/byyyccctest/static/ysjl/logo/logoVertical.png");
        }

        activity.setAddTime(new Timestamp(System.currentTimeMillis()));
        this.setAddressGeo(activity);
        this.insert(activity);

        // 获取活动图集
        formReqVo = activity.getForms().get(2);
        picVal = (List) formReqVo.getVal();
        if (picVal != null && picVal.size() > 0) {
            List<YsjlActivityPic> picList = new ArrayList<>();
            YsjlActivityPic activityPic = null;
            for (String url : picVal) {
                activityPic = new YsjlActivityPic();
                activityPic.setActivityId(activity.getId());
                activityPic.setPic(url);
                activityPic.setAddTime(new Timestamp(System.currentTimeMillis()));
                picList.add(activityPic);
            }
            this.ysjlActivityPicService.insertBatch(picList);
        }

        // 获取活动流程
        formReqVo = activity.getForms().get(3);
        List<Map<String, Object>> flowVal = (List) formReqVo.getVal();
        if (flowVal != null && flowVal.size() > 0) {
            if (((String) flowVal.get(0).get("title")).contains("默认流程")) {
                return activity;
            }
            else {
                List<YsjlActivityFlow> flowList = new ArrayList<>();
                YsjlActivityFlow activityFlow = null;
                int sort = 0;
                for (Map flow : flowVal) {
                    activityFlow = new YsjlActivityFlow();
                    activityFlow.setSort(sort);
                    activityFlow.setActivityId(activity.getId());
                    activityFlow.setTitle((String) flow.get("title"));
                    activityFlow.setAddTime(new Timestamp(System.currentTimeMillis()));
                    flowList.add(activityFlow);
                    sort++;
                }
                this.ysjlActivityFlowService.insertBatch(flowList);
            }
        }
        */
        return null;
    }

    @Override
    public String join(List<YsjlActivityEnroll> enrollList) {
        String activityId = enrollList.get(0).getActivityId();
        YsjlActivity activity = selectById(activityId);
        if (DateUtils.getSecondOfTwoDate(activity.getStartTime(), new Date()) > 0L)
            return "早干嘛去了！";
        List<String> nameList = new ArrayList<>();
        for (YsjlActivityEnroll enroll : enrollList) {
            if (nameList.contains(enroll.getShowName()))
                return "不要接重复名！";
            nameList.add(enroll.getShowName());
        }
        if (enrollList.size() > 6)
            return "最多报6个！";
        String userId = enrollList.get(0).getUserId();
        YsjlUser user = this.ysjlUserService.selectById(userId);
        if (!"1".equals(user.getStatus())) {
            return "你被关禁闭了！";
        }

        if (activity.getCateId() == ActivityCateEnum.PROMOTION.getCode()) {
            if (enrollList.size() > 1)
                return "晋级赛自己报！";
            if (user.getScore() < YsjlGlobal.RANK_SCORE_MAP.get(user.getRank()))
                return "积分不够晋级！";
            YsjlActivity sameActivity = this.baseMapper.querySameTimeActivity(activity.getStartTime(), activity.getEndTime(), activity.getAddressLat(), activity.getAddressLon());
            if (sameActivity == null)
                return "群活动还没发！";
            List<YsjlActivityEnroll> promotionEnrollList = this.ysjlActivityEnrollService.queryMyListByActivityId(sameActivity.getId(), userId);
            if (promotionEnrollList == null || promotionEnrollList.isEmpty()) {
                promotionEnrollList = new ArrayList<>(enrollList.size());
                for (YsjlActivityEnroll enroll : enrollList) {
                    try {
                        promotionEnrollList.add((YsjlActivityEnroll) BeanUtils.cloneBean(enroll));
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                }
                inertEnrollList(sameActivity, user, promotionEnrollList);
            }
        }
        inertEnrollList(activity, user, enrollList);
        return null;
    }

    @Override
    public String deleteEnroll(YsjlActivityEnroll enroll) {
        YsjlActivityEnroll activityEnroll = this.ysjlActivityEnrollService.selectById(enroll.getId());
        YsjlActivity activity = this.selectById(activityEnroll.getActivityId());
        if (!"admin".equals(enroll.getUserName())) {
            if (DateUtils.getSecondOfTwoDate(activity.getStopTime(), new Date()) > 0) {
                return "没有撤退可言！";
            }
        }

        this.ysjlActivityEnrollService.deleteById(activityEnroll.getId());
        YsjlUser user = null;
        if (!"admin".equals(enroll.getUserName())) {
            user = this.ysjlUserService.selectById(activityEnroll.getUserId());
        }
        else {
            user = this.ysjlUserService.queryByName("admin");
        }

        YsjlLog log = new YsjlLog();
        log.setUserId(activityEnroll.getUserId());
        log.setActivityId(activityEnroll.getActivityId());
        log.setAddTime(new Timestamp(System.currentTimeMillis()));
        log.setContent(YsjlGlobal.decodeName(user.getName()) + ":" + YsjlGlobal.decodeName(activityEnroll.getShowName()) + "「删」");
        ysjlLogService.insert(log);

        // TODO 发送消息
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(activity.getStartTime());
        StringBuilder content = (new StringBuilder()).append(DateUtils.formatDate(activity.getStartTime(), Global.PATTERN_YYYYMMMDD)).append("日").append(YsjlGlobal.WEEK[calendar.get(Calendar.DAY_OF_WEEK) - 1]).append(activity.getAddress()).append(" ").append(log.getContent());
        List<YsjlActivityEnroll> enrollList = this.ysjlActivityEnrollService.queryListByActivityId(activity.getId());
        OAProducer oAProducer = (OAProducer) SpringContextHolder.getBean("oAProducer");
        oAProducer.send("badminton", "badminton", content.append("共接龙").append(enrollList.size()).append("人").toString());

        return null;
    }

    @Override
    public String updateActivity(YsjlActivity activity) {
        // 校验
        YsjlActivity dbActivity = this.selectById(activity.getId());
        if (ActivityStatusEnum.GOON.getCode() != dbActivity.getStatus()) {
            return "活动已停用！";
        }
        if (DateUtils.getSecondOfTwoDate(dbActivity.getStartTime(), new Date()) > 0) {
            return "活动已停止！";
        }

        // 保存
        this.setAddressGeo(activity);
        activity.setEditTime(new Timestamp(System.currentTimeMillis()));
        this.updateById(activity);

        /*
        // 获取活动费用
        FormReqVo formReqVo = activity.getForms().get(0);
        String feeVal = (String) formReqVo.getVal();
        if (StringUtils.isNotEmpty(feeVal)) {
            activity.setFee(feeVal);
        }
        else {
            activity.setFee("2-3小时，人均30-40！");
        }

        // 获取封面图片
        formReqVo = activity.getForms().get(1);
        List<String> picVal = (List) formReqVo.getVal();
        if (picVal != null && picVal.size() > 0) {
            activity.setPic(picVal.get(0));
        }
        else {
            activity.setPic("http://ccc.baheal.com/byyyccctest/static/ysjl/logo/logoVertical.png");
        }

        this.setAddressGeo(activity);
        activity.setEditTime(new Timestamp(System.currentTimeMillis()));
        this.updateById(activity);

        // 获取活动图集
        this.ysjlActivityPicService.deleteByActivityId(activity.getId());
        formReqVo = activity.getForms().get(2);
        picVal = (List) formReqVo.getVal();
        if (picVal != null && picVal.size() > 0) {
            List<YsjlActivityPic> picList = new ArrayList<>();
            YsjlActivityPic activityPic = null;
            for (String url : picVal) {
                activityPic = new YsjlActivityPic();
                activityPic.setActivityId(activity.getId());
                activityPic.setPic(url);
                activityPic.setAddTime(new Timestamp(System.currentTimeMillis()));
                picList.add(activityPic);
            }
            this.ysjlActivityPicService.insertBatch(picList);
        }

        // 获取活动流程
        this.ysjlActivityFlowService.deleteByActivityId(activity.getId());
        formReqVo = activity.getForms().get(3);
        List<Map<String, Object>> flowVal = (List) formReqVo.getVal();
        if (flowVal != null && flowVal.size() > 0) {
            if (((String) flowVal.get(0).get("title")).contains("默认流程")) {
                return null;
            }
            else {
                List<YsjlActivityFlow> flowList = new ArrayList<>();
                YsjlActivityFlow activityFlow = null;
                int sort = 0;
                for (Map flow : flowVal) {
                    activityFlow = new YsjlActivityFlow();
                    activityFlow.setSort(sort);
                    activityFlow.setActivityId(activity.getId());
                    activityFlow.setTitle((String) flow.get("title"));
                    activityFlow.setAddTime(new Timestamp(System.currentTimeMillis()));
                    flowList.add(activityFlow);
                    sort++;
                }
                this.ysjlActivityFlowService.insertBatch(flowList);
            }
        }
        */
        return null;
    }

    @Override
    public String deleteActivity(String id) {
        this.ysjlActivityEnrollService.deleteEnrollByUser(id, null);
        this.ysjlActivityPicService.deleteByActivityId(id);
        this.ysjlActivityFlowService.deleteByActivityId(id);
        this.deleteById(id);
        return null;
    }

    @Override
    public String generateQRCode(HttpServletRequest request, String activityId, String qrPath) {
        String res = HttpUtils.get("https://api.weixin.qq.com/cgi-bin/token", "grant_type=client_credential&appid=wxe45a395077d171ea&secret=21af424dfe7d7fa9a58d1dd7bb611cf6");

        ObjectMapper mapper = new ObjectMapper();
        Map<String, String> map = null;
        try {
            map = mapper.readValue(res, Map.class);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }

        // TODO 小程序上线后，需要根据实际path传参
        String token = map.get("access_token");
        Map<String, String> jsonMap = new HashMap<>();
        jsonMap.put("scene", "qr");
        // /projects/activityyu/pages/default/index/default_index
        jsonMap.put("path", "page/index/index");
        byte[] qrBytes = null;
        try {
            qrBytes = HttpUtils.postWithJsonRetBytes("https://api.weixin.qq.com/wxa/getwxacodeunlimit?ACCESS_TOKEN=" + token, mapper.writeValueAsString(jsonMap));
        } catch (JsonProcessingException e) {
            logger.error(e.getMessage(), e);
        }

        String filename = this.extractFilename("static/ysjl");
        File desc = null;
        OutputStream os = null;
        try {
            desc = this.getAbsoluteFile(request.getServletContext().getRealPath("/"), filename);
            os = new FileOutputStream(desc.getAbsoluteFile());
            os.write(qrBytes);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                }
            }
        }
        StringBuffer requestURL = request.getRequestURL();
        String path = requestURL.toString().substring(0, requestURL.toString().indexOf(request.getServletPath()));
        YsjlActivity activity = this.selectById(activityId);
        activity.setQr(path + "/" + filename);
        this.updateById(activity);
        return activity.getQr();
    }

    @Override
    public YsjlActivity myJoinInfo(String id, String userId) {
        YsjlActivity activity = this.selectById(id);
        List<YsjlActivityEnroll> activityEnrollList = this.ysjlActivityEnrollService.queryListByActivityId(id);
        if (activityEnrollList != null && !activityEnrollList.isEmpty()) {
            List<YsjlActivityEnroll> successEnrollList = new ArrayList<>();
            int userJoinCnt = 0;
            int userSuccessJoinCnt = 0;
            int maxCnt = activity.getMaxCnt();
            YsjlActivityEnroll enroll = null;
            for (int i = 0; i < activityEnrollList.size(); i++) {
                enroll = activityEnrollList.get(i);
                if (enroll.getUserId().equals(userId)) {
                    activity.setUserId(enroll.getUserId());
                    userJoinCnt++;
                    if (i < maxCnt) {
                        userSuccessJoinCnt++;
                    }
                }
            }
            activity.setUserJoinCnt(userJoinCnt);
            activity.setUserSuccessJoinCnt(userSuccessJoinCnt);
            activity.setEnrollList(activityEnrollList);
        }
        List<YsjlLog> logList = this.ysjlLogService.queryMyListByActivityId(id, userId);
        activity.setLogList(logList);
        return activity;
    }

    /**
     * 设置地址经纬度
     * @param activity
     */
    private void setAddressGeo(YsjlActivity activity) {
        String address = activity.getAddress();
        if (address.contains("南京路") ) {
            activity.setAddressLat(36.10739f);
            activity.setAddressLon(120.38003f);
        }
        if (address.contains("全民") ) {
            activity.setAddressLat(36.134804f);
            activity.setAddressLon(120.38826f);

        }
        if (address.contains("国信") ) {
            activity.setAddressLat(36.105206f);
            activity.setAddressLon(120.443474f);

        }
    }

    /**
     * 获取文件名
     * @param baseDir
     * @return
     */
    private String extractFilename(String baseDir) {
        String filename = baseDir + "/" + DateFormatUtils.format(new Date(), "yyyy/MM/dd") + "/" + System.currentTimeMillis() + ".jpg";
        return filename;
    }

    /**
     * 生成对应文件
     * @param uploadDir
     * @param filename
     * @return
     * @throws IOException
     */
    private File getAbsoluteFile(String uploadDir, String filename) throws IOException {
        uploadDir = FilenameUtils.normalizeNoEndSeparator(uploadDir);
        File desc = new File(uploadDir + "/" + filename);
        if (!desc.getParentFile().exists()) {
            desc.getParentFile().mkdirs();
        }
        if (!desc.exists()) {
            desc.createNewFile();
        }
        return desc;
    }

    /**
     * 计算相应的积分
     */
    @Override
    public void countScore() {
        List<YsjlActivity> activityList = this.baseMapper.queryNotOverActivity();
        if (activityList == null || activityList.isEmpty()) {
            return;
        }

        for (YsjlActivity activity : activityList) {
            List<YsjlActivityEnroll> enrollList = this.ysjlActivityEnrollService.queryListByActivityId(activity.getId());
            enrollList = enrollList.stream().sorted(Comparator.comparing(YsjlActivityEnroll::getUserId)).collect(Collectors.toList());

            // 判断是否存在固定搭档帮助报名的情况
            List<String> userIdList = new ArrayList<>();
            String beforeUserId = null;
            for (YsjlActivityEnroll enroll : enrollList) {
                if (enroll.getUserId().equals(beforeUserId)) {
                    userIdList.add(YsjlGlobal.PARTNER.get(enroll.getUserId()));
                }
                else {
                    userIdList.add(enroll.getUserId());
                }
                beforeUserId = enroll.getUserId();
            }

            // 加分，更新
            List<YsjlUser> userList = this.ysjlUserService.selectBatchIds(userIdList);
            for (YsjlUser user : userList) {
                user.setCurrentScore(user.getCurrentScore() + YsjlGlobal.SCORE_PER_ACTIVITY);
                user.setScore(user.getScore() + YsjlGlobal.SCORE_PER_ACTIVITY);
                user.setActivityCnt(user.getActivityCnt() + 1);
            }

            this.ysjlUserService.updateBatchById(userList);

            activity.setStatus(ActivityStatusEnum.OVER.getCode());

        }

        this.updateBatchById(activityList);

        // 看看过期得会员
        List<YsjlUser> userList = this.ysjlUserService.queryVipOverUser();
        if (userList == null || userList.isEmpty()) {
            return;
        }
        for (YsjlUser user : userList) {
            user.setVipLevel(0);
            user.setVipEndDate(null);
        }
        this.ysjlUserService.updateBatchById(userList);
    }

    private void inertEnrollList(YsjlActivity activity, YsjlUser user, List<YsjlActivityEnroll> enrollList) {
        List<YsjlActivityEnroll> insertList = new ArrayList<>();
        List<YsjlActivityEnroll> updateList = new ArrayList<>();
        StringBuilder sb = (new StringBuilder(YsjlGlobal.decodeName(user.getName()))).append(":");
        for (YsjlActivityEnroll enroll : enrollList) {
            enroll.setShowName(YsjlGlobal.encodeName(enroll.getShowName()));
            if (StringUtils.isEmpty(enroll.getId())) {
                enroll.setActivityId(activity.getId());
                enroll.setUserId(user.getId());
                enroll.setAddTime(new Timestamp(System.currentTimeMillis()));
                enroll.setEditTime(new Timestamp(System.currentTimeMillis()));
                sb.append(YsjlGlobal.decodeName(enroll.getShowName())).append("「增」").append(";");
                insertList.add(enroll);
            } else {
                enroll.setEditTime(new Timestamp(System.currentTimeMillis()));
                sb.append(YsjlGlobal.decodeName(enroll.getShowName())).append("「更」").append(";");
                updateList.add(enroll);
            }
        }
        if (!insertList.isEmpty())
            this.ysjlActivityEnrollService.insertBatch(insertList);
        if (!updateList.isEmpty())
            this.ysjlActivityEnrollService.updateBatchById(updateList);
        YsjlLog log = new YsjlLog();
        log.setUserId(user.getId());
        log.setActivityId(activity.getId());
        log.setAddTime(new Timestamp(System.currentTimeMillis()));
        log.setContent(sb.toString());
        this.ysjlLogService.insert(log);

        // TODO 发送消息
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(activity.getStartTime());
        StringBuilder content = (new StringBuilder()).append(DateUtils.formatDate(activity.getStartTime(), Global.PATTERN_YYYYMMMDD)).append("日").append(YsjlGlobal.WEEK[calendar.get(Calendar.DAY_OF_WEEK) - 1]).append(activity.getAddress()).append(" ").append(sb.toString());
        enrollList = this.ysjlActivityEnrollService.queryListByActivityId(activity.getId());
        OAProducer oAProducer = (OAProducer) SpringContextHolder.getBean("oAProducer");
        oAProducer.send("badminton", "badminton", content.append("共接龙").append(enrollList.size()).append("人").toString());
    }

}
